package com.zpp.system.service.sysuser.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zpp.common.core.constants.HttpConstants;
import com.zpp.common.core.domain.LoginUser;
import com.zpp.common.core.domain.Result;
import com.zpp.common.core.domain.vo.LoginUserVO;
import com.zpp.common.core.enums.ResultCode;
import com.zpp.common.core.enums.UserIdentity;
import com.zpp.common.security.exception.ServiceException;
import com.zpp.common.security.service.TokenService;
import com.zpp.system.domain.sysuser.SysUser;
import com.zpp.system.domain.sysuser.dto.SysUserSaveDTO;
import com.zpp.system.mapper.sysuser.SysUserMapper;
import com.zpp.system.service.sysuser.ISysUserService;
import com.zpp.system.utils.BCryptUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;


import static com.zpp.system.utils.BCryptUtils.matchesPassword;

@Service
@RefreshScope  //通过nacos动态更新配置
public class SysUserServiceImpl implements ISysUserService {

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private TokenService tokenService;

    @Value("${jwt.secret}")  //从nacos配置中心数据获取
    private String secret;

    @Override
    public Result<String> login(String userAccount, String password) {

        //查询用户对象
        //select user_id, password from `tb_sys_user` where user_account = #{userAccount} 查询出来密码后，封装为sysUser对象返回
        //查到一条数据返回对象，查到0条数据返回null，查看多条抛出TooManyResultsException异常
        SysUser sysUser = sysUserMapper.selectOne(new LambdaQueryWrapper<SysUser>().
                select(SysUser::getUserId, SysUser::getPassword, SysUser::getNickName)
                .eq(SysUser::getUserAccount, userAccount));

        //用户不存在
        if(sysUser == null) {
            return Result.fail( ResultCode.FAILED_USER_NOT_EXISTS);
        }

        //密码不正确
        if(!matchesPassword(password, sysUser.getPassword())) {
            return Result.fail(ResultCode.FAILED_LOGIN);
        }

        //验证成功
        //将敏感信息存入redis，并返回token
        String token = tokenService.createToken(sysUser.getUserId(), secret, UserIdentity.ADMIN, sysUser.getNickName(),null);
        //4.返回给客户端
        return Result.success(token);
    }

    @Override
    public boolean logout(String token) {
        // 如果前端设置了令牌前缀，则裁剪掉前缀
        if (StrUtil.isNotEmpty(token) && token.startsWith(HttpConstants.PREFIX)) {
            token = token.replaceFirst(HttpConstants.PREFIX, StrUtil.EMPTY);
        }
        return tokenService.deleteToken(token, secret);
    }

    @Override
    public Result<LoginUserVO> info(String token) {
        // 如果前端设置了令牌前缀，则裁剪掉前缀
        if (StrUtil.isNotEmpty(token) && token.startsWith(HttpConstants.PREFIX)) {
            token = token.replaceFirst(HttpConstants.PREFIX, StrUtil.EMPTY);
        }

        LoginUser loginUser = tokenService.getInfo(token, secret);
        //获取失败，不存在登录对象
        if(loginUser == null) {
            return Result.fail();
        }
        //获取成功，创建VO对象进行返回
        LoginUserVO loginUserVO = new LoginUserVO();
        loginUserVO.setNickName(loginUser.getNickName());
        return Result.success(loginUserVO);
    }

    @Override
    public int add(SysUserSaveDTO saveDTO) {
        //查询数据库中当前用户是否已经存在
        SysUser sysUser = sysUserMapper.selectOne(new LambdaQueryWrapper<SysUser>().
                eq(SysUser::getUserAccount, saveDTO.getUserAccount()));
        if(sysUser != null) {
            //用户已经存在
            //抛出异常信息
            throw new ServiceException(ResultCode.AILED_USER_EXISTS);
        }

        //将dto转换为实体类
        SysUser entity = new SysUser();
        entity.setUserAccount(saveDTO.getUserAccount());
        entity.setNickName(saveDTO.getNickName());
        entity.setPassword(BCryptUtils.encryptPassword(saveDTO.getPassword()));

        return  sysUserMapper.insert(entity);
    }
}
